﻿#include "EditorNotificationViewModel.h"
#include "EditorNotificationModel.h"
#include "EditorNotificationItemViewModel.h"
#include "EditorNotificationItemModel.h"
#include "Object/NewObject.h"
#include "Framework/Editor.h"


void REditorNotificationViewModel::BindModel(TSharedObjectPtr<REditorNotificationModel> InModel)
{
    Model = InModel;

    Model->OnItemsChanged.Bind([this]()
    {
        UpdateItems();
        OnItemsChanged.ExecuteIfBound();
    });
}

int64_t REditorNotificationViewModel::GetItemsCount() const
{
    return Items.Num();
}

TSharedObjectPtr<REditorNotificationItemViewModel> REditorNotificationViewModel::GetItem(int64_t Index) const
{
    return Items[Index];
}

void REditorNotificationViewModel::ClearItems()
{
    Model->ClearItems();
}

void REditorNotificationViewModel::UpdateItems()
{
    Items.Clear();
    for(int64_t i = 0; i < Model->GetItemsCount(); ++i)
    {
        TSharedObjectPtr<REditorNotificationItemViewModel> ItemViewModel 
            = NewObject<REditorNotificationItemViewModel>(
                REditor::Get()->GetViewModelClass(
                    Model->GetItem(i)->GetClass())
                , this
            );
        ItemViewModel->BindModel(Model->GetItem(i));
        Items.Add(ItemViewModel);
    }
}


bool REditorNotificationViewModel::IsItemVisible(int64_t Index) const
{
    switch(Model->GetVisibility())
    {
        case REditorNotificationModel::EVisibility::AllVisible:
            return true;
        
        case REditorNotificationModel::EVisibility::LastVisible:
            return Index == Model->GetItemsCount() - 1;

        case REditorNotificationModel::EVisibility::NoneVisible:
            return false;

        default:
            assert(false);
            return false;
    };
}

float REditorNotificationViewModel::GetItemsHeight() const
{
    switch(Model->GetVisibility())
    {
        case REditorNotificationModel::EVisibility::AllVisible:
            {
                float Height = 0.f;
                for(auto& Item : Items)
                {
                    Height += Item->GetHeight();
                }
                return Height;
            }
            break;
        case REditorNotificationModel::EVisibility::LastVisible:
            return Items.Empty() ? 0.f : Items.Last()->GetHeight();
            break;
        case REditorNotificationModel::EVisibility::NoneVisible:
            return 0.f;
            break;

        default:
            assert(false);
            return 0.f;
    }

}

float REditorNotificationViewModel::GetItemHeight(int64_t Index) const
{
    if(IsItemVisible(Index))
    {
        return Items[Index]->GetHeight();
    }
    return 0;
}

bool REditorNotificationViewModel::IsTitleVisible() const
{
    return Model->IsTitleVisible();
}

void REditorNotificationViewModel::HideWholeNotification()
{
    Model->SetVisibility(REditorNotificationModel::EVisibility::NoneVisible);
}

void REditorNotificationViewModel::ToggleDonDisturb()
{
    Model->ToggleDontDisturb();
}
